/*
 * GlassPanel.java
 *
 * Created on 21.06.2007, 22:18:58
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package de.tor.util;

/*
 * GlassPanel.java
 *
 * Created on 22. November 2005, 10:40
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */


import de.tor.util.listeners.EditorDragListener;
import java.awt.Dimension;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
import javax.swing.JPanel;

/** <b> GlassPanel for Drag'n Drop of files. </b>
 * <UL> <LI>  File   : $RCSfile: GlassPanel.java,v $
 * <LI>  Date   : $Date: 2005/08/18 09:56:09 $
 * <LI>  Version: $Revision: 1.4 $
 * <LI>  Author: Volker Hartmann
 * </UL>
 */
public class GlassPanel extends JPanel implements DropTargetListener{//, DragUpdateListener {
    
    /** Vector mit allen Objekten, die informiert werden sollen. */
    protected Vector listeners = new Vector(1);
    private int iMouseXPos;
    private int iMouseYPos;
    private int iComponentWidth;
    private int iComponentHeight;
    private Dimension minimumSize;
    private List<EditorDragListener> mDragListeners;
    
    
    /** Creates a new instance of GlassPanel */
    public GlassPanel() {
        super();

        minimumSize = new Dimension(20,20);
        DropTarget target = new DropTarget(this, this);
        mDragListeners = new LinkedList();
    }
    
    public Dimension getMinimumSize(){
        return minimumSize;
    }
    
    public void setMinimumSize(Dimension size){
        minimumSize = size;
    }
    
    public synchronized void addEditorDragListener(EditorDragListener listener){
        mDragListeners.add(listener);
    }
    
    /**
     * Called when the drag operation has terminated with a drop on
     * the operable part of the drop site for the <code>DropTarget</code>
     * registered with this listener.
     * <p>
     * This method is responsible for undertaking
     * the transfer of the data associated with the
     * gesture. The <code>DropTargetDropEvent</code>
     * provides a means to obtain a <code>Transferable</code>
     * object that represents the data object(s) to
     * be transfered.<P>
     * From this method, the <code>DropTargetListener</code>
     * shall accept or reject the drop via the
     * acceptDrop(int dropAction) or rejectDrop() methods of the
     * <code>DropTargetDropEvent</code> parameter.
     * <P>
     * Subsequent to acceptDrop(), but not before,
     * <code>DropTargetDropEvent</code>'s getTransferable()
     * method may be invoked, and data transfer may be
     * performed via the returned <code>Transferable</code>'s
     * getTransferData() method.
     * <P>
     * At the completion of a drop, an implementation
     * of this method is required to signal the success/failure
     * of the drop by passing an appropriate
     * <code>boolean</code> to the <code>DropTargetDropEvent</code>'s
     * dropComplete(boolean success) method.
     * <P>
     * Note: The data transfer should be completed before the call  to the
     * <code>DropTargetDropEvent</code>'s dropComplete(boolean success) method.
     * After that, a call to the getTransferData() method of the
     * <code>Transferable</code> returned by
     * <code>DropTargetDropEvent.getTransferable()</code> is guaranteed to
     * succeed only if the data transfer is local; that is, only if
     * <code>DropTargetDropEvent.isLocalTransfer()</code> returns
     * <code>true</code>. Otherwise, the behavior of the call is
     * implementation-dependent.
     * <P>
     * @param pDTDE the <code>DropTargetDropEvent</code>
     */
    public void drop(DropTargetDropEvent pDTDE) {
        String[] pathNameList = null;
        try {
            Transferable tr = pDTDE.getTransferable();
            
            if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                pDTDE.acceptDrop(DnDConstants.ACTION_COPY);
                String value = (String)tr.getTransferData(DataFlavor.stringFlavor);
                for(EditorDragListener listener : mDragListeners){
                    listener.fireDropEvent(value, pDTDE.getLocation().x, pDTDE.getLocation().y);
                }
                
                pDTDE.getDropTargetContext().dropComplete(true);
            } else {
                pDTDE.rejectDrop();
            }
        } catch (IOException io) {
            io.printStackTrace();
            pDTDE.rejectDrop();
        } catch (UnsupportedFlavorException ufe) {
            ufe.printStackTrace();
            pDTDE.rejectDrop();
        }
    }
    
    /**
     * Called while a drag operation is ongoing, when the mouse pointer has
     * exited the operable part of the drop site for the
     * <code>DropTarget</code> registered with this listener.
     *
     * @param dte the <code>DropTargetEvent</code>
     */
    public void dragExit(DropTargetEvent dte) {
        for(EditorDragListener listener : mDragListeners){
            listener.fireDragExitEvent();
        }
    }
    
    /**
     * Called if the user has modified
     * the current drop gesture.
     * <P>
     * @param pDTDE the <code>DropTargetDragEvent</code>
     */
    public void dropActionChanged(DropTargetDragEvent pDTDE) {
    }
    
    /**
     * Called when a drag operation is ongoing, while the mouse pointer is still
     * over the operable part of the drop site for the <code>DropTarget</code>
     * registered with this listener.
     *
     * @param pDTDE the <code>DropTargetDragEvent</code>
     */
    public void dragOver(DropTargetDragEvent pDTDE) {
        for(EditorDragListener listener : mDragListeners){
            try {
                Transferable tr = pDTDE.getTransferable();
                if (tr.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                    String value = (String)tr.getTransferData(DataFlavor.stringFlavor);
                    listener.fireDragEnteredEvent(value, pDTDE.getLocation().x, pDTDE.getLocation().y);
                }
            } catch (IOException io) {
                io.printStackTrace();
            } catch (UnsupportedFlavorException ufe) {
                ufe.printStackTrace();
            }
            
        }
    }
    
    /**
     * Called while a drag operation is ongoing, when the mouse pointer enters
     * the operable part of the drop site for the <code>DropTarget</code>
     * registered with this listener.
     *
     * @param pDTDE the <code>DropTargetDragEvent</code>
     */
    public void dragEnter(DropTargetDragEvent pDTDE) {
    }
    
  /*  public void fireNewPositionEvent(int xPos, int yPos, int width, int height) {
        iMouseXPos = xPos;
        iMouseYPos = yPos;
        iComponentWidth = width;
        iComponentHeight = height;
        repaint();
    }
   
    public void fireDragFinishedEvent() {
        iMouseXPos = 0;
        iMouseYPos = 0;
        iComponentWidth = 0;
        iComponentHeight = 0;
        repaint();
    }*/
}
